package com.nhncorp.ntaf;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

import fit.Fixture;
import fit.RunningState;
import fitlibrary.table.Tables;
import fitlibrary.utility.TableListener;
import fitlibrary.utility.TestResults;

public class NtafExecuteData {
	private static final int UNKNOWN_KEYWORD = -1;
	private static final int ITERATE = 0;
	private static final int LOOP = 1;
	private static final int IF = 2;
	private static final int SEQUENCE = 3;
	private static final int PARALLEL = 4;
	private static final int PARALLEL_ITERATE = 5;
	private static final int TIMER = 6;

	private Fixture flowFixture;
	private Tables tables;
	private int from;
	private int to;
	private TestResults testResults;
	private TableListener tableListener;
	private RunningState childState;
	private NtafFlowState state;

	private String strVar;
	private String strFrom;
	private String strTo;
	private String strBy;
	private String strWhile;
	private String strUntil;
	private int loopFrom;
	private int loopTo;
	private int incrementBy;

	private int keywordType;

	private String strIndexvar;
	private ArrayList<String> iterateList;
	
	private String strCondition;
	
	private CountDownLatch doneLatch;
	private ArrayList<NtafThread> threadArray;
	
	private String strDuration;

	public NtafExecuteData(FlowFixture parentFixture, Tables tables, int from, int to, TableListener tableListener,
			NtafFlowState state, RunningState childState) {
		this.flowFixture = parentFixture;
		this.tables = tables;
		this.from = from;
		this.to = to;
		this.tableListener = tableListener;
		this.testResults = tableListener.getTestResults();
		this.childState = childState;
		this.state = state;
		keywordType = UNKNOWN_KEYWORD;

	}

	public void teardownAttributesAndSymbols() {
		switch (keywordType) {
			case LOOP:
				NtafDoTraverse.ntafInfo.removeSymbol("var");
				NtafDoTraverse.ntafInfo.removeAttribute("var");
				NtafDoTraverse.ntafInfo.removeAttribute("from");
				NtafDoTraverse.ntafInfo.removeAttribute("to");
				NtafDoTraverse.ntafInfo.removeAttribute("by");
				NtafDoTraverse.ntafInfo.removeAttribute("while");
				NtafDoTraverse.ntafInfo.removeAttribute("until");
				break;
			case PARALLEL_ITERATE:
			case ITERATE:
				NtafDoTraverse.ntafInfo.removeSymbol("var");
				NtafDoTraverse.ntafInfo.removeSymbol("indexvar");
				NtafDoTraverse.ntafInfo.removeAttribute("var");
				NtafDoTraverse.ntafInfo.removeAttribute("indexvar");
				break;
			case IF:
				NtafDoTraverse.ntafInfo.removeSymbol("expr");
				NtafDoTraverse.ntafInfo.removeAttribute("expr");
				break;
			case TIMER:
				NtafDoTraverse.ntafInfo.removeAttribute("duration");
				break;
		}

	}

	public void initializeTimerAttributes() {
		strDuration = NtafDoTraverse.ntafInfo.getReplaceSymbolAttribute("duration");
		
		keywordType = TIMER;
	}
	
	public void initializeParallelIterateAttributes() {
		strVar = NtafDoTraverse.ntafInfo.getAttribute("var").trim();
		strIndexvar = NtafDoTraverse.ntafInfo.getAttribute("indexvar").trim();
		iterateList = new ArrayList<String>(NtafDoTraverse.ntafInfo.getInList());
		
		initializeParallelAttributes();
		keywordType = PARALLEL_ITERATE;
	}
	
	public void initializeIterateAttributes() {
		strVar = NtafDoTraverse.ntafInfo.getAttribute("var").trim();
		strIndexvar = NtafDoTraverse.ntafInfo.getAttribute("indexvar").trim();
		iterateList = new ArrayList<String>(NtafDoTraverse.ntafInfo.getInList());

		keywordType = ITERATE;

	}

	public void initializeLoopAttributes() {
		//get the value of attributes
		strVar = NtafDoTraverse.ntafInfo.getAttribute("var").trim();
		strFrom = NtafDoTraverse.ntafInfo.getReplaceSymbolAttribute("from");
		strTo = NtafDoTraverse.ntafInfo.getReplaceSymbolAttribute("to");
		strBy = NtafDoTraverse.ntafInfo.getReplaceSymbolAttribute("by");
		strWhile = NtafDoTraverse.ntafInfo.getReplaceSymbolAttribute("while");
		strUntil = NtafDoTraverse.ntafInfo.getReplaceSymbolAttribute("until");

		keywordType = LOOP;

		if (strFrom.equals(""))
			loopFrom = 1;
		else {
			loopFrom = Integer.parseInt(strFrom);
		}

		if (strTo.equals(""))
			loopTo = loopFrom + 1;
		else
			loopTo = Integer.parseInt(strTo);

		if (strBy.equals(""))
			incrementBy = 1;
		else
			incrementBy = Integer.parseInt(strBy);
	}
	
	public void initializeIfAttributes() {
		strCondition = NtafDoTraverse.ntafInfo.getAttribute("expr").trim();
		
		keywordType = IF;
	}
	
	public void initializeSequenceAttributes() {
		keywordType = SEQUENCE;
	}
	
	public void initializeParallelAttributes() {
		doneLatch = null;
		threadArray = new ArrayList<NtafThread>();
		keywordType = PARALLEL;
	}

	public String getStrIndexvar() {
		return this.strIndexvar;
	}

	public ArrayList<String> getIterateList() {
		return this.iterateList;
	}

	public Fixture getFlowFixture() {
		return this.flowFixture;
	}

	public Tables getTables() {
		return this.tables;
	}

	public int getFrom() {
		return this.from;
	}

	public int getTo() {
		return this.to;
	}

	public TestResults getTestResults() {
		return this.testResults;
	}

	public TableListener getTableListener() {
		return this.tableListener;
	}

	public RunningState getChildState() {
		return this.childState;
	}

	public String getStrVar() {
		return this.strVar;
	}

	public String getStrFrom() {
		return this.strFrom;
	}

	public String getStrTo() {
		return this.strTo;
	}

	public String getStrBy() {
		return this.strBy;
	}

	public String getStrWhile() {
		return this.strWhile;
	}

	public String getStrUntil() {
		return this.strUntil;
	}

	public int getLoopFrom() {
		return this.loopFrom;
	}

	public int getLoopTo() {
		return this.loopTo;
	}

	public void setLoopTo(int i) {
		this.loopTo = i;
	}

	public int getIncrementBy() {
		return this.incrementBy;
	}

	public void adjustLoopToValue() {
		if (strTo.equals(""))
			this.loopTo += 2;
	}

	public String getCellParameterText(int index) {
		return tables.table(index).row(0).text(1);
	}

	public String getKeywordText(int index) {
		return tables.table(index).row(0).text(0);
	}

	public int getBreakCount() {
		int result = 0;

		switch (keywordType) {
			case LOOP:
				result = loopTo;
				break;
			case PARALLEL_ITERATE:
			case ITERATE:
				result = iterateList.size();
				break;
		}

		return result;
	}
	
	public NtafFlowState getState() {
		return this.state;
	}
	
	public String getStrCondition() {
		return this.strCondition;
	}
	
	public CountDownLatch getDoneLatch() {
		return this.doneLatch;
	}

	public ArrayList<NtafThread> getThreadArray() {
		return this.threadArray;
	}
	
	public void setDoneLatch(CountDownLatch doneLatch) {
		this.doneLatch = doneLatch;
	}

	public String getStrDuration() {
		return this.strDuration;
	}

	public void setStrDuration(String strDuration) {
		this.strDuration = strDuration;
	}
}